# coding=UTF-8
import os

base_path = os.getcwd().split('\\StockMonitor')[0] + '\\StockMonitor\\'
stock_path = base_path.split('\\stock')[0] + '\\stock\\'

from utils import json_util, k_util, statisticalutil, date_util

# 1.股价在中轨和上轨中间运行，处于多头市场，说明较为强势，同样，股价在下轨和中轨中间运行，处于空头市场，说明较为弱势；
# 2.股价由下向上穿越中轨时，为加仓信号，但可能会受到中轨的压力；a
# 3.当股价由上向下中轨时，为减仓信号，同样可能会受到中轨的支撑；a
# 4.股价穿越上轨时，卖出信号。 同样当股价穿越下轨时，是买入信号；a
# 5.当布林线的开口越来越小的时候，说明股价的波动在减小，多空双方力量趋于一致，此时股价将会选择突破方向；a
# 6.当布林线的开口越来越大的时候，说明一方的力量在增强，股价在进行突破；a
# 中轨既然是均线，就有趋势的指示作用，如果向上说明趋势向上，反之向下。

# 状态4为T+L- boll_list使用到最新一天的布林值
# boll形态指示表
# 1:形态 '<'  :开口越来越大的时候，说明一方的力量在增强，股价在进行突破
# 2:形态 '>'  :开口越来越小的时候，说明股价的波动在减小，多空双方力量趋于一致，此时股价将会选择突破方向
# 3:形态 '><','<>' :参照1,2
# 4:形态 'T+' :当股价穿越上限压力线时，卖点信号
# 5:形态 'L-' :当股价穿越下限支撑线时，买点信号
# 6:形态 '十+' :当股价由下向上穿越中界限时，为加码信号；
# 7:形态 '十-' :当股价由上向下穿越中界线时，为卖出信号.
# 8:形态 'L'  :股价在下轨和中轨中间运行，处于空头市场，说明较为弱势
# 9:形态 'T'  :股价在中轨和上轨中间运行，处于多头市场，说明较为强势

boll_dict = {
    '<': '开口越来越大，一方的力量在增强，股价在进行突破',
    '>': '开口越来越小，股价的波动在减小，多空趋于一致，将会选择突破方向',
    '><': '开口开始变大，一方的力量在增强，股价选择进行突破',
    '<>': '开口开始变小，波动在减小，多空趋于一致，股价波动平复',
    'T+': '股价穿越上限压力线，卖点信号',
    'L-': '股价穿越下限支撑线，买点信号',
    '十+': '股价由下向上穿越中界限，加码信号',
    '十-': '股价由上向下穿越中界线，卖出信号',
    'L1': '股价在下轨和中轨中间运行，处于空头市场，较为弱势',
    'T2': '股价在中轨和上轨中间运行，处于多头市场，较为强势',
}


def judge_form(boll_list, rt_price):
    # 小于三个不判断
    if len(boll_list) < 3:
        return ''
    # boll_info = {'rq': rq, 'sp': sp, 'MB': MB, 'UP': UP, 'DN': DN, 'MD': MD, 'WIDTH': WIDTH}
    boll_info = json_util.info_to_json(boll_list[0])
    boll_info1 = json_util.info_to_json(boll_list[1])
    boll_info2 = json_util.info_to_json(boll_list[2])
    form = ''
    # 判断开口去三天值
    md0 = boll_info['MD']
    mb0 = boll_info['MB']
    md1 = boll_info1['MD']
    md2 = boll_info2['MD']
    if md0 >= md1 and md1 >= md2:
        form += '<'
    if md0 < md1 and md1 < md2:
        form += '>'
    if md0 >= md1 and md1 < md2:
        form += '><'
    if md0 < md1 and md1 >= md2:
        form += '<>'
    # 1，当股价穿越上限压力线时，卖点信号；
    form += ':'
    up = boll_info['UP']
    if rt_price > up:
        form += 'T+'
    # 2，当股价穿越下限支撑线时，买点信号；
    dn = boll_info['DN']
    if rt_price < dn:
        form += 'L-'
    # 3，当股价由下向上穿越中界限时，为加码信号；
    sp1 = boll_info1['sp']
    mb1 = boll_info1['MB']
    dn1 = boll_info1['DN']
    up1 = boll_info1['UP']
    if sp1 < mb1 and rt_price > mb0 and rt_price < up:
        level = round((rt_price - mb0) / md0 * 5)
        form += '十+' + str(level)
    # 4，当股价由上向下穿越中界线时，为卖出信号.
    if sp1 > mb1 and rt_price < mb0 and rt_price > dn:
        level = round((mb0 - rt_price) / md0 * 5)
        form += '十-' + str(level)
    # 5，股价在下轨和中轨中间运行，处于空头市场，说明较为弱势
    if sp1 > dn1 and sp1 < mb1 and rt_price > dn and rt_price < mb0:
        level = round((mb0 - rt_price) / md0 * 5)
        form += 'L' + str(level)
    # 6，股价在中轨和上轨中间运行，处于多头市场，说明较为强势
    if sp1 < up1 and sp1 > mb1 and rt_price < up and rt_price > mb0:
        level = round((rt_price - mb0) / md0 * 5)
        form += 'T' + str(level)
    form += ':' + str(boll_info['WIDTH'])
    return form


# size 取得尺寸
# sp 当天的最新收盘价（实时价格）小于等于0 自动获取
def boll_latest(code, size, sp):
    day_k_use = []
    if sp > 0:
        day_k_use.append({'sp': sp, 'rq': date_util.get_date_str()})
        day_k_use += (k_util.day_k_local_previous(code, size + 20))
    else:
        day_k_use = k_util.day_k_rt(code, size + 20)
    if len(day_k_use) <= 20 + size:
        return []
    close = []
    sum = 0
    for num in range(20):
        spj = float(json_util.info_to_json(day_k_use[num])['sp'])
        sum += spj
        close.append(spj)
    boll_list = []
    for i in range(size):
        if i != 0:
            k0 = json_util.info_to_json(day_k_use[i - 1])
            k1 = json_util.info_to_json(day_k_use[i + 19])
            sp0 = float(k0['sp'])
            sp1 = float(k1['sp'])
            sum = sum + sp1 - sp0
            close[(i + 19) % 20] = sp1
        MB = round(sum / 20, 2)
        MD = statisticalutil.standard_deviation(close)
        UP = round(MB + 2 * MD, 2)
        DN = round(MB - 2 * MD, 2)
        WIDTH = round(4 * MD / MB, 4)  # 极限宽指标 小于0.10的股票随时有可能发生突破。
        rq = json_util.info_to_json(day_k_use[i])['rq']
        spj = float(json_util.info_to_json(day_k_use[i])['sp'])
        boll_info = {'rq': rq, 'sp': spj, 'MB': MB, 'UP': UP, 'DN': DN, 'MD': MD, 'WIDTH': WIDTH}
        boll_list.append(boll_info)
    return boll_list


# 获取 boll 最多支持天数100天
# start_rq : 开始日期 格式'2020-11-02' 倒序
# size   : 开始日期往前几天
def get_boll_interval(code, start_rq, size):
    day_k_result = k_util.day_k_all_local(code)
    day_k_use = []
    close = []
    sum = 0
    day_k_len = len(day_k_result)
    for i in range(day_k_len):
        day_k = json_util.info_to_json(day_k_result[i])
        if day_k['rq'] == start_rq:
            # 判断是否超出最大长度
            if day_k_len <= i + size + 19:
                print(code + '######计算boll长度不够重新获取#######' + start_rq)
                day_k_result = k_util.day_k_online_up_cache(code, i + size + 60)
            for j in range(size + 20):
                day_k = json_util.info_to_json(day_k_result[i + j])
                day_k_use.append(day_k)
                if j < 20:
                    sp = float(day_k['sp'])
                    sum += sp
                    close.append(sp)
            break
    boll_list = []
    # 中轨线(MB) = N日的移动平均线
    # 上轨线(UP) = 中轨线 + 两倍的标准差
    # 下轨线(DN) = 中轨线 - 两倍的标准差
    for i in range(size):
        if i != 0:
            k0 = day_k_use[i - 1]
            k1 = day_k_use[i + 19]
            sp0 = float(k0['sp'])
            sp1 = float(k1['sp'])
            sum = sum + sp1 - sp0
            close[(i + 19) % 20] = sp1
        MB = round(sum / 20, 2)
        MD = statisticalutil.standard_deviation(close)
        UP = round(MB + 2 * MD, 2)
        DN = round(MB - 2 * MD, 2)
        WIDTH = round(4 * MD / MB, 4)  # 极限宽指标 小于0.10的股票随时有可能发生突破。
        rq = json_util.info_to_json(day_k_use[i])['rq']
        sp = float(json_util.info_to_json(day_k_use[i])['sp'])
        boll_info = {'rq': rq, 'sp': sp, 'MB': MB, 'UP': UP, 'DN': DN, 'MD': MD, 'WIDTH': WIDTH}
        boll_list.append(boll_info)
    return boll_list


# 老方法 -- 未优化
# 获取 macd 最多支持天数100天
# start_rq : 开始日期 格式'2020-11-02' 倒序
# size   : 开始日期往前几天
def get_boll_interval_v1(code, start_rq, size):
    day_k_result = k_util.day_k_local_previous(code, 120)
    day_k_use = []
    for i in range(len(day_k_result)):
        day_k = json_util.info_to_json(day_k_result[i])
        if day_k['rq'] == start_rq:
            for j in range(size + 20):
                day_k_use.append(day_k_result[i + j])
            break
    boll_list = []
    for i in range(size):
        close = []
        sum = 0
        for j in range(20):
            day_k = day_k_use[i + j]
            sp = float(json_util.info_to_json(day_k)['sp'])
            sum += sp
            close.append(sp)
        MB = round(sum / 20, 2)
        MD = statisticalutil.standard_deviation(close)
        UP = round(MB + 2 * MD, 2)
        DN = round(MB - 2 * MD, 2)
        WIDTH = round(4 * MD / MB, 4)  # 极限宽指标 小于0.10的股票随时有可能发生突破。
        rq = json_util.info_to_json(day_k_use[i])['rq']
        sp = float(json_util.info_to_json(day_k_use[i])['sp'])
        boll_info = {'rq': rq, 'sp': sp, 'MB': MB, 'UP': UP, 'DN': DN, 'MD': MD, 'WIDTH': WIDTH}
        boll_list.append(boll_info)
    return boll_list


if __name__ == '__main__':
    boll_list1 = get_boll_interval('600031', '2020-08-06', 3)
    # boll_list2 = boll_latest('600031', 10, 38.28)
    # info = judge_form(boll_list2, 38.28)
    # print(info)
    # for i in range(10):
    #     # print(boll_list1[i])
    #     print(boll_list2[i])
    # print()
